--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/backend/test_name_overwrite_fixes.py 1b7051a8108fe1fc2df2f1affa65b3719bb578e6 (1b7051a8) Text, 19.70 KB
T8b949e"""Tests for the contact/conversation name overwrite bug fixes.
Covers:
Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL Announce upsert preserving app_data via COALESCE when new value is NULL
Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour Contacts DAO upsert conflict behaviour
Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set) Custom display name lifecycle (set, get, delete, re-set)
Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation Contact name update propagation
Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts Edge cases: empty strings, unicode, very long names, concurrent upserts
"""
Tff7b72import T7ee787base64
Tff7b72import T7ee787os
Tff7b72import T7ee787tempfile
Tff7b72import T7ee787pytest
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787announces Tff7b72import Te6edf3AnnounceDAO
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787contacts Tff7b72import Te6edf3ContactsDAO
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787provider Tff7b72import Te6edf3DatabaseProvider
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787schema Tff7b72import Te6edf3DatabaseSchema
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787meshchat_utils Tff7b72import Te6edf3parse_lxmf_display_name
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787umsgpack Tff7b72as T7ee787msgpack
Tff7b72except Tf85149ImportErrorTb4b4b4:
Te6edf3msgpack Tff7b72= Tff7b72None
Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8fftemp_dbTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3fdTb4b4b4, Te6edf3path Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffmkstempTb4b4b4(Te6edf3suffixTff7b72=Ta5d6ff"Ta5d6ff.dbTa5d6ff"Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3fdTb4b4b4)
Tff7b72yield Te6edf3path
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3pathTb4b4b4)
Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffproviderTb4b4b4(Te6edf3temp_dbTb4b4b4)Tb4b4b4:
Te6edf3p Tff7b72= Te6edf3DatabaseProviderTb4b4b4(Te6edf3temp_dbTb4b4b4)
Te6edf3schema Tff7b72= Te6edf3DatabaseSchemaTb4b4b4(Te6edf3pTb4b4b4)
Te6edf3schemaTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Tff7b72yield Te6edf3p
Te6edf3pTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffannounce_daoTb4b4b4(Te6edf3providerTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3AnnounceDAOTb4b4b4(Te6edf3providerTb4b4b4)
Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffcontacts_daoTb4b4b4(Te6edf3providerTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3ContactsDAOTb4b4b4(Te6edf3providerTb4b4b4)
Tff7b72def Td2a8ff_make_app_data_b64Tb4b4b4(Te6edf3nameTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72if Te6edf3msgpack Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3nameTff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Te6edf3packed Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Te6edf3nameTff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3packedTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ff_base_announceTb4b4b4(Te6edf3destTff7b72=Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffsome_dataTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Te6edf3destTb4b4b4,
Ta5d6ff"Ta5d6ffaspectTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffidentity_hashTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffiTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4,
Ta5d6ff"Ta5d6ffidentity_public_keyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4,
Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4: Te6edf3app_dataTb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff60Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: T79c0ff8Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: T79c0ff0.9Tb4b4b4,
Tb4b4b4}
T8b949e# ---------------------------------------------------------------------------
T8b949e# Announce upsert COALESCE tests
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestAnnounceUpsertPreservesAppDataTb4b4b4:
T8b949e"""The core bug: upserting an announce with app_data=None must NOT wipe
the previously stored app_data."""
Tff7b72def Td2a8fftest_null_app_data_preserves_existingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6fforiginal_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fforiginal_nameTa5d6ff"
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fforiginal_nameTa5d6ff"
Tff7b72def Td2a8fftest_new_app_data_overwrites_existingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffold_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffnew_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffnew_nameTa5d6ff"
Tff7b72def Td2a8fftest_first_insert_with_null_app_dataTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72def Td2a8fftest_first_null_then_real_then_null_againTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6ffaTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffreal_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffreal_nameTa5d6ff"
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffreal_nameTa5d6ff"
Tff7b72def Td2a8fftest_multiple_null_upserts_no_degradationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6ffbTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffstable_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff10Tb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffstable_nameTa5d6ff"
Tff7b72def Td2a8fftest_other_fields_still_update_on_null_app_dataTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6ffcTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(
Tb4b4b4{Tff7b72*Tff7b72*Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffkeep_meTa5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff50Tb4b4b4}
Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(
Tb4b4b4{Tff7b72*Tff7b72*Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff90Tb4b4b4}
Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkeep_meTa5d6ff"
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4] Tff7b72== Tff7b72-T79c0ff90
Tff7b72def Td2a8fftest_empty_string_app_data_is_not_nullTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6ffeTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffgood_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ff"
T8b949e# ---------------------------------------------------------------------------
T8b949e# Custom display name lifecycle
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestCustomDisplayNameLifecycleTb4b4b4:
Tff7b72def Td2a8fftest_set_and_getTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffAliceTa5d6ff"
Tff7b72def Td2a8fftest_update_overwritesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffBobTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffBobTa5d6ff"
Tff7b72def Td2a8fftest_delete_removesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffdelete_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72is Tff7b72None
Tff7b72def Td2a8fftest_get_nonexistent_returns_noneTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffnonexistentTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72None
Tff7b72def Td2a8fftest_delete_nonexistent_is_noopTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffdelete_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffnonexistentTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_set_after_deleteTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffFirstTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffdelete_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffSecondTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffSecondTa5d6ff"
Tff7b72def Td2a8fftest_unicode_display_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Tffea00\u5c71Tffea00\u7530Tffea00\u592aTffea00\u90ceTa5d6ff"Tb4b4b4)
Tff7b72assert Tb4b4b4(
Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Tffea00\u5c71Tffea00\u7530Tffea00\u592aTffea00\u90ceTa5d6ff"
Tb4b4b4)
Tff7b72def Td2a8fftest_very_long_display_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff" Tff7b72* T79c0ff10000
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Te6edf3long_nameTb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Te6edf3long_name
Tff7b72def Td2a8fftest_empty_string_display_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ff"
Tff7b72def Td2a8fftest_multiple_destinations_independentTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest2Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffBobTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffdelete_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest1Ta5d6ff"Tb4b4b4) Tff7b72is Tff7b72None
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6ffdest2Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffBobTa5d6ff"
T8b949e# ---------------------------------------------------------------------------
T8b949e# Contacts DAO edge cases
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestContactsEdgeCasesTb4b4b4:
Tff7b72def Td2a8fftest_add_contact_upsert_preserves_addressesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(
Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih1Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Ta5d6ff"Ta5d6fflxmf1Ta5d6ff"Tb4b4b4, Te6edf3lxst_addressTff7b72=Ta5d6ff"Ta5d6fflxst1Ta5d6ff"
Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(
Ta5d6ff"Ta5d6ffAlice UpdatedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih1Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Tff7b72NoneTb4b4b4, Te6edf3lxst_addressTff7b72=Tff7b72None
Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih1Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffAlice UpdatedTa5d6ff"
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6fflxmf_addressTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fflxmf1Ta5d6ff"
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6fflxst_addressTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fflxst1Ta5d6ff"
Tff7b72def Td2a8fftest_add_contact_upsert_replaces_name_unconditionallyTb4b4b4(
Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3provider
Tb4b4b4)Tb4b4b4:
T8b949e"""Verifies add_contact always overwrites name on conflict."""
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffReal NameTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih2Ta5d6ff"Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffOverwrittenTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih2Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih2Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffOverwrittenTa5d6ff"
Tff7b72def Td2a8fftest_update_contact_partialTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih3Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Ta5d6ff"Ta5d6fflx3Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT id FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih3Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Te6edf3cid Tff7b72= Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]
Te6edf3contacts_daoTff7b72.Td2a8ffupdate_contactTb4b4b4(Te6edf3cidTb4b4b4, Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffAlice RenamedTa5d6ff"Tb4b4b4)
Te6edf3updated Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE id = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3cidTb4b4b4,Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3updatedTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffAlice RenamedTa5d6ff"
Tff7b72assert Te6edf3updatedTb4b4b4[Ta5d6ff"Ta5d6fflxmf_addressTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fflx3Ta5d6ff"
Tff7b72def Td2a8fftest_update_contact_no_fields_is_noopTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffNoOpTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih4Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT id FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih4Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffupdate_contactTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]Tb4b4b4)
Te6edf3updated Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE id = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]Tb4b4b4,Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3updatedTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffNoOpTa5d6ff"
Tff7b72def Td2a8fftest_update_contact_clear_imageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(
Ta5d6ff"Ta5d6ffWithImageTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih5Ta5d6ff"Tb4b4b4, Te6edf3custom_imageTff7b72=Ta5d6ff"Ta5d6ffdata:image/png;base64,abcTa5d6ff"
Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT id FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih5Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Tff7b72assert Te6edf3row Tff7b72is Tff7b72not Tff7b72None
Te6edf3cid Tff7b72= Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]
Te6edf3contacts_daoTff7b72.Td2a8ffupdate_contactTb4b4b4(Te6edf3cidTb4b4b4, Te6edf3clear_imageTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3updated Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE id = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3cidTb4b4b4,Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3updatedTb4b4b4[Ta5d6ff"Ta5d6ffcustom_imageTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72def Td2a8fftest_get_contact_by_identity_hash_matches_lxmf_addressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffVia LXMFTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih6Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Ta5d6ff"Ta5d6fflxmf6Ta5d6ff"Tb4b4b4)
Te6edf3result Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contact_by_identity_hashTb4b4b4(Ta5d6ff"Ta5d6fflxmf6Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3result Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffVia LXMFTa5d6ff"
Tff7b72def Td2a8fftest_get_contact_by_identity_hash_matches_lxst_addressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffVia LXSTTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih7Ta5d6ff"Tb4b4b4, Te6edf3lxst_addressTff7b72=Ta5d6ff"Ta5d6fflxst7Ta5d6ff"Tb4b4b4)
Te6edf3result Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contact_by_identity_hashTb4b4b4(Ta5d6ff"Ta5d6fflxst7Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3result Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffVia LXSTTa5d6ff"
Tff7b72def Td2a8fftest_delete_nonexistent_contactTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffdelete_contactTb4b4b4(T79c0ff99999Tb4b4b4)
Tff7b72def Td2a8fftest_unicode_contact_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Tffea00\u00c9Ta5d6ffmilie Tffea00\u00d6Ta5d6ffsterreichTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih8Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT * FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih8Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Tffea00\u00c9Ta5d6ffmilie Tffea00\u00d6Ta5d6ffsterreichTa5d6ff"
Tff7b72def Td2a8fftest_contacts_search_case_insensitive_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffCharlie DeltaTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih9Ta5d6ff"Tb4b4b4)
Te6edf3results Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contactsTb4b4b4(Te6edf3searchTff7b72=Ta5d6ff"Ta5d6ffcharlieTa5d6ff"Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3resultsTb4b4b4) Tff7b72>Tff7b72= T79c0ff1
Tff7b72assert Tffa657anyTb4b4b4(Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffCharlie DeltaTa5d6ff" Tff7b72for Te6edf3r Tff7b72in Te6edf3resultsTb4b4b4)
Tff7b72def Td2a8fftest_contacts_count_with_searchTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffAlphaTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih10Ta5d6ff"Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffBetaTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih11Ta5d6ff"Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffAlphaTwoTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih12Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3contacts_daoTff7b72.Td2a8ffget_contacts_countTb4b4b4(Te6edf3searchTff7b72=Ta5d6ff"Ta5d6ffalphaTa5d6ff"Tb4b4b4) Tff7b72== T79c0ff2
Tff7b72assert Te6edf3contacts_daoTff7b72.Td2a8ffget_contacts_countTb4b4b4(Tb4b4b4) Tff7b72== T79c0ff3
T8b949e# ---------------------------------------------------------------------------
T8b949e# parse_lxmf_display_name fallback behaviour
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestParseLxmfDisplayNameFallbackTb4b4b4:
Tff7b72def Td2a8fftest_none_returns_anonymous_peerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3parse_lxmf_display_nameTb4b4b4(Tff7b72NoneTb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72def Td2a8fftest_none_with_custom_defaultTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3parse_lxmf_display_nameTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3default_valueTff7b72=Ta5d6ff"Ta5d6ffFallbackTa5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffFallbackTa5d6ff"
Tff7b72def Td2a8fftest_none_with_none_defaultTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3parse_lxmf_display_nameTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3default_valueTff7b72=Tff7b72NoneTb4b4b4) Tff7b72is Tff7b72None
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffskipifTb4b4b4(Te6edf3msgpack Tff7b72is Tff7b72NoneTb4b4b4, Te6edf3reasonTff7b72=Ta5d6ff"Ta5d6ffmsgpack not availableTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_valid_app_data_returns_nameTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffTestNodeTa5d6ff"
Te6edf3packed Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Te6edf3nameTff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4]Tb4b4b4)
Te6edf3b64 Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3packedTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3parse_lxmf_display_nameTb4b4b4(Te6edf3b64Tb4b4b4) Tff7b72== Te6edf3name
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffskipifTb4b4b4(Te6edf3msgpack Tff7b72is Tff7b72NoneTb4b4b4, Te6edf3reasonTff7b72=Ta5d6ff"Ta5d6ffmsgpack not availableTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_empty_name_in_app_dataTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3packed Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Ta5d6ffbTa5d6ff"Ta5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4]Tb4b4b4)
Te6edf3b64 Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3packedTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Te6edf3result Tff7b72= Te6edf3parse_lxmf_display_nameTb4b4b4(Te6edf3b64Tb4b4b4)
Tff7b72assert Te6edf3result Tff7b72== Ta5d6ff"Ta5d6ff"
Tff7b72def Td2a8fftest_garbage_base64Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Te6edf3parse_lxmf_display_nameTb4b4b4(Ta5d6ff"Ta5d6ff!!!not-base64!!!Ta5d6ff"Tb4b4b4)
Tff7b72assert Tffa657isinstanceTb4b4b4(Te6edf3resultTb4b4b4, Tffa657strTb4b4b4)
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffskipifTb4b4b4(Te6edf3msgpack Tff7b72is Tff7b72NoneTb4b4b4, Te6edf3reasonTff7b72=Ta5d6ff"Ta5d6ffmsgpack not availableTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_none_name_in_app_data_returns_defaultTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3packed Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4]Tb4b4b4)
Te6edf3b64 Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3packedTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3parse_lxmf_display_nameTb4b4b4(Te6edf3b64Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
T8b949e# ---------------------------------------------------------------------------
T8b949e# Integration: announce + custom name + contact name resolution priority
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestNameResolutionPriorityTb4b4b4:
T8b949e"""Simulates the priority chain:
custom_display_name > announce app_data > contact name > 'Anonymous Peer'
"""
Tff7b72def Td2a8fftest_custom_name_wins_over_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(
Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffAnnounceAliceTa5d6ff"Tb4b4b4)
Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4, Ta5d6ff"Ta5d6ffCustomAliceTa5d6ff"Tb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffCustomAliceTa5d6ff"
Tff7b72def Td2a8fftest_announce_used_when_no_customTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffAnnounceOnlyTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffAnnounceOnlyTa5d6ff"
Tff7b72def Td2a8fftest_fallback_to_anonymous_when_nothingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72def Td2a8fftest_contact_name_used_when_no_announce_no_customTb4b4b4(
Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3provider
Tb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffContactAliceTa5d6ff"Tb4b4b4, Te6edf3destTb4b4b4, Te6edf3lxmf_addressTff7b72=Te6edf3destTb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3contact Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contact_by_identity_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3contact_name Tff7b72= Te6edf3contactTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3contact Tff7b72else Tff7b72None
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Te6edf3contact_name Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffContactAliceTa5d6ff"
Tff7b72def Td2a8fftest_clearing_custom_name_falls_back_to_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Ta5d6ff"Ta5d6ffAnnounceNameTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4, Ta5d6ff"Ta5d6ffCustomTa5d6ff"Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffdelete_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffAnnounceNameTa5d6ff"
Tff7b72def Td2a8fftest_wiping_announce_with_contact_still_resolvesTb4b4b4(
Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4, Te6edf3contacts_dao
Tb4b4b4)Tb4b4b4:
T8b949e"""After the COALESCE fix, this should not happen, but if app_data
was already NULL, the contact name should still be available."""
Te6edf3dest Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffContactFallbackTa5d6ff"Tb4b4b4, Te6edf3destTb4b4b4, Te6edf3lxmf_addressTff7b72=Te6edf3destTb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Te6edf3destTb4b4b4, Te6edf3app_dataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3row Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announce_by_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3contact Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contact_by_identity_hashTb4b4b4(Te6edf3destTb4b4b4)
Te6edf3contact_name Tff7b72= Te6edf3contactTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3contact Tff7b72else Tff7b72None
Te6edf3display Tff7b72= Te6edf3custom Tff7b72or Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72or Te6edf3contact_name Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Tff7b72assert Te6edf3display Tff7b72== Ta5d6ff"Ta5d6ffContactFallbackTa5d6ff"
T8b949e# ---------------------------------------------------------------------------
T8b949e# Announce trim does not break name resolution
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestAnnounceTrimSafetyTb4b4b4:
Tff7b72def Td2a8fftest_trim_does_not_remove_active_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3announce_daoTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4:
Te6edf3announce_daoTff7b72.Td2a8ffupsert_announceTb4b4b4(
Te6edf3_base_announceTb4b4b4(Te6edf3destTff7b72=Ta5d6fffTa5d6ff"Tffd700{Te6edf3iTffd700:Ta5d6ff032xTffd700}Ta5d6ff"Tb4b4b4, Te6edf3app_dataTff7b72=Ta5d6fffTa5d6ff"Ta5d6ffname_Tffd700{Te6edf3iTffd700}Ta5d6ff"Tb4b4b4)
Tb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8fftrim_announces_for_aspectTb4b4b4(Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4, Te6edf3max_rowsTff7b72=T79c0ff3Tb4b4b4)
Te6edf3remaining Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_announcesTb4b4b4(Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3remainingTb4b4b4) Tff7b72== T79c0ff3
Tff7b72for Te6edf3r Tff7b72in Te6edf3remainingTb4b4b4:
Tff7b72assert Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ffname_Ta5d6ff"Tb4b4b4)
T8b949e# ---------------------------------------------------------------------------
T8b949e# Contacts + custom display name sync edge cases
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestContactCustomNameSyncTb4b4b4:
Tff7b72def Td2a8fftest_renaming_contact_and_custom_name_independentlyTb4b4b4(
Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3announce_daoTb4b4b4, Te6edf3provider
Tb4b4b4)Tb4b4b4:
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffAliceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih20Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Ta5d6ff"Ta5d6fflx20Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT id FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih20Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Te6edf3cid Tff7b72= Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6fflx20Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffAlice CustomTa5d6ff"Tb4b4b4)
Te6edf3contacts_daoTff7b72.Td2a8ffupdate_contactTb4b4b4(Te6edf3cidTb4b4b4, Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffAlice RenamedTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6fflx20Ta5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffAlice CustomTa5d6ff"
Te6edf3contact Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contactTb4b4b4(Te6edf3cidTb4b4b4)
Tff7b72assert Te6edf3contactTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffAlice RenamedTa5d6ff"
Tff7b72def Td2a8fftest_synced_rename_updates_bothTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contacts_daoTb4b4b4, Te6edf3announce_daoTb4b4b4, Te6edf3providerTb4b4b4)Tb4b4b4:
T8b949e"""Simulates what the UI should do: update both contact and custom name."""
Te6edf3contacts_daoTff7b72.Td2a8ffadd_contactTb4b4b4(Ta5d6ff"Ta5d6ffBobTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffih21Ta5d6ff"Tb4b4b4, Te6edf3lxmf_addressTff7b72=Ta5d6ff"Ta5d6fflx21Ta5d6ff"Tb4b4b4)
Te6edf3row Tff7b72= Te6edf3providerTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT id FROM contacts WHERE remote_identity_hash = ?Ta5d6ff"Tb4b4b4, Tb4b4b4(Ta5d6ff"Ta5d6ffih21Ta5d6ff"Tb4b4b4,Tb4b4b4)
Tb4b4b4)
Te6edf3cid Tff7b72= Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]
Te6edf3new_name Tff7b72= Ta5d6ff"Ta5d6ffBob RenamedTa5d6ff"
Te6edf3contacts_daoTff7b72.Td2a8ffupdate_contactTb4b4b4(Te6edf3cidTb4b4b4, Te6edf3nameTff7b72=Te6edf3new_nameTb4b4b4)
Te6edf3announce_daoTff7b72.Td2a8ffupsert_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6fflx21Ta5d6ff"Tb4b4b4, Te6edf3new_nameTb4b4b4)
Te6edf3contact Tff7b72= Te6edf3contacts_daoTff7b72.Td2a8ffget_contactTb4b4b4(Te6edf3cidTb4b4b4)
Te6edf3custom Tff7b72= Te6edf3announce_daoTff7b72.Td2a8ffget_custom_display_nameTb4b4b4(Ta5d6ff"Ta5d6fflx21Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3contactTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3new_name
Tff7b72assert Te6edf3custom Tff7b72== Te6edf3new_name
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────